#include "QBProviceInfo.h"

#include <string.h>

char QBPROVINCEINFO::Empty = 0;
QBPROVINCEINFO::QBPROVINCEINFO() {
  Area_Code[0] = 0;
  Area_Level[0] = 0;
  Area_Upper_Grade_Code[0] = 0;
  Area_Name = &QBPROVINCEINFO::Empty;
  Area_English_Name = &QBPROVINCEINFO::Empty;
}

QBPROVINCEINFO::QBPROVINCEINFO(const QBPROVINCEINFO& rhs) {
  Area_Code[0] = 0;
  Area_Level[0] = 0;
  Area_Upper_Grade_Code[0] = 0;

  memcpy(Area_Code, rhs.Area_Code, sizeof(Area_Code));
  memcpy(Area_Level, rhs.Area_Level, sizeof(Area_Level));
  memcpy(Area_Upper_Grade_Code, rhs.Area_Upper_Grade_Code,
         sizeof(Area_Upper_Grade_Code));

  Area_Name = &QBPROVINCEINFO::Empty;
  Area_English_Name = &QBPROVINCEINFO::Empty;
  SetAreaName(rhs.Area_Name);
  SetAreaEnglishName(rhs.Area_English_Name);
}

QBPROVINCEINFO& QBPROVINCEINFO::operator=(const QBPROVINCEINFO& rhs) {
  memcpy(Area_Code, rhs.Area_Code, sizeof(Area_Code));
  memcpy(Area_Level, rhs.Area_Level, sizeof(Area_Level));
  memcpy(Area_Upper_Grade_Code, rhs.Area_Upper_Grade_Code,
         sizeof(Area_Upper_Grade_Code));

  SetAreaName(rhs.Area_Name);
  SetAreaEnglishName(rhs.Area_English_Name);
  return *this;
}

QBPROVINCEINFO::~QBPROVINCEINFO() {
  if (Area_Name != &QBPROVINCEINFO::Empty && Area_Name != nullptr) {
    free(Area_Name);
  }
  if (Area_English_Name != &QBPROVINCEINFO::Empty &&
      Area_English_Name != nullptr) {
    free(Area_English_Name);
  }
}

void QBPROVINCEINFO::SetAreaName(const char* name) {
  if (Area_Name == name) return;
  if (Area_Name != &QBPROVINCEINFO::Empty && Area_Name != nullptr) {
    free(Area_Name);
  }
  if (name == nullptr || name[0] == 0) {
    Area_Name = &QBPROVINCEINFO::Empty;
  } else {
    Area_Name = (char*)malloc(strlen(name) + 1);
    strcpy(Area_Name, name);
  }
}

void QBPROVINCEINFO::SetAreaEnglishName(const char* name) {
  if (Area_English_Name == name) return;
  if (Area_English_Name != &QBPROVINCEINFO::Empty &&
      Area_English_Name != nullptr) {
    free(Area_English_Name);
  }
  if (name == nullptr || name[0] == 0) {
    Area_English_Name = &QBPROVINCEINFO::Empty;
  } else {
    Area_English_Name = (char*)malloc(strlen(name) + 1);
    strcpy(Area_English_Name, name);
  }
}

//////////////////////////////////////////////////////////////////////
// class CQBProvinceInfo

CQBProvinceInfo::CQBProvinceInfo() {}

CQBProvinceInfo::~CQBProvinceInfo() { Clear(); }

bool CQBProvinceInfo::Add(QBPROVINCEINFO& info) {
  // std::lock_guard<std::mutex> locker(m_mutex);//TODO:
  if (info.Area_Code[0] == '\0') return false;
  m_map[info.Area_Code] = info;
  return true;
}

bool CQBProvinceInfo::Clear() {
  std::lock_guard<std::mutex> locker(m_mutex);
  m_map.clear();
  return true;
}

CQBProvinceInfo& CQBProvinceInfo::instance() {
  static CQBProvinceInfo s_pi;
  return s_pi;
}

const QBPROVINCEINFO* CQBProvinceInfo::GetProviceInfo(const std::string& id) {
  std::lock_guard<std::mutex> locker(m_mutex);
  std::map<std::string, QBPROVINCEINFO>::iterator it = m_map.find(id);
  if (it != m_map.end()) {
    return &it->second;
  }
  return NULL;
}

void CQBProvinceInfo::DumpStatus(int mode) const {}
